package main

import (
	"flag"
	"fmt"
	"log"
	"math/rand"
	"strconv"
	"sync"
	"time"

	mqtt "github.com/eclipse/paho.mqtt.golang"
)

func main() {
	//tcp://localhost:1883
	//tcp://localhost:9999
	//tcp://172.16.0.103:9999
	//tcp://172.16.0.98:1883
	//tcp://localhost:9999
	//addr := flag.String("addr", "tcp://172.16.0.98:1883", "mqtt broker addr")
	addr := flag.String("addr", "tcp://localhost:9999", "mqtt broker addr")
	flag.Parse()
	fmt.Println("addr: ", *addr)

	waitGroup := sync.WaitGroup{}
	waitGroup.Add(1)
	go mqttConnPubMsgTask(*addr, 1, &waitGroup, func(client mqtt.Client, msg mqtt.Message) {
		fmt.Printf("Pub Client Topic : %s \n", msg.Topic())
		fmt.Printf("Pub Client msg : %s \n", msg.Payload())
	})
	waitGroup.Wait()
}

func mqttConnPubMsgTask(addr string, taskId int, waitGroup *sync.WaitGroup, messagePubHandler mqtt.MessageHandler) {
	defer waitGroup.Done()

	clinetOptions := mqtt.NewClientOptions().
		AddBroker(addr).
		SetUsername("admin").
		SetPassword("public")

	clinetOptions.SetClientID(fmt.Sprintf("yomo-edge pub client: %d-%d", taskId, time.Now().Unix()))

	clinetOptions.SetDefaultPublishHandler(messagePubHandler)

	clinetOptions.SetConnectTimeout(time.Duration(60) * time.Second)

	client := mqtt.NewClient(clinetOptions)

	if token := client.Connect(); token.WaitTimeout(time.Duration(60)*time.Second) &&
		token.Wait() && token.Error() != nil {
		log.Fatalf("[Pub] yomo-edge connect error, taskId: %d, error: %s \n", taskId, token.Error())
		return
	}

	i := 0
	for {
		i++
		time.Sleep(time.Duration(2) * time.Second)

		var text string
		var topic string
		if i%2 == 0 {
			topic = "thermometer"
			rand.Seed(time.Now().UnixNano())
			fs := randFloats(0.0, 100.00, 4)
			text = fmt.Sprintf("[{\"tem\":%v,\"hum\":%v},{\"tem\":%v,\"hun\":%v}]",
				decimal(fs[0]), decimal(fs[1]), decimal(fs[2]), decimal(fs[3]))
		} else {
			topic = "test"
			text = fmt.Sprintf("{\"tag\":[\"5G\",\"v%d\"]}", i)
		}
		//topic = "test"
		//text = fmt.Sprintf("{\"tag\":[\"5G\",\"v%d\"]}", i)
		token := client.Publish(topic, 1, false, text)
		fmt.Printf("Emitter publish msg to mqtt broker, taskId: %d, count: %d, text : %s, topic: %s, \n",
			taskId, i, text, topic)
		token.Wait()
	}
}

func randFloats(min, max float64, n int) []float64 {
	res := make([]float64, n)
	for i := range res {
		res[i] = min + rand.Float64()*(max-min)
	}
	return res
}

func decimal(value float64) float64 {
	value, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", value), 64)
	return value
}
